﻿using System;
using UnityEngine;
using Excel;
using System.Data;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections;
using System.Collections.Generic;

namespace Guide.Editor.Serialize
{
    public class SerializeReader
    {
        private TableStructure tableStructure = null;

        private TableContent rowContainer = null;
        private TableContent columnContainer = null;

        /// <summary>
        /// 获得表头结构
        /// </summary>
        /// <returns></returns>
        public TableStructure GetTableStructure()
        {
            return tableStructure;
        }
        /// <summary>
        /// 获取行数
        /// </summary>
        /// <returns></returns>
        public int GetRowLength()
        {
            if (null != rowContainer)
                return rowContainer.GetLength();
            return 0;
        }
        /// <summary>
        /// 获取列数
        /// </summary>
        /// <returns></returns>
        public int GetColumnLength()
        {
            if (null != columnContainer)
                return columnContainer.GetLength();
            return 0;
        }
        /// <summary>
        /// 得到某一行的所有数据，包括空数据
        /// </summary>
        /// <param name="row"></param>
        /// <param name="rowList"></param>
        public void GetRowAllData(int row, List<string> rowList)
        {
            if(null == rowContainer || row < 0 || row >= rowContainer.GetLength())
            {
                Debug.LogError("获取行数据参数不合法。" + row);
                return;
            }

           rowContainer.GetLineData(row, rowList);
        }
        /// <summary>
        /// 得到某一行的所有数据，不包括空数据
        /// </summary>
        /// <param name="row"></param>
        /// <param name="rowList"></param>
        public void GetRowDataExceptEmpty(int row, List<string> rowList)
        {
            if (null == rowContainer || row < 0 || row >= rowContainer.GetLength())
            {
                Debug.LogError("获取行数据参数不合法。" + row);
                return;
            }

            rowContainer.GetLineDataExceptEmpty(row, rowList);
        }
        /// <summary>
        /// 得到某一列的所有数据，包括空数据
        /// </summary>
        /// <param name="column"></param>
        /// <param name="columnList"></param>
        public void GetColumnAllData(int column, List<string> columnList)
        {
            if (null == columnContainer || column < 0 || column >= columnContainer.GetLength())
            {
                Debug.LogError("获取列数据参数不合法。" + column);
                return;
            }

            columnContainer.GetLineData(column, columnList);
        }
        /// <summary>
        /// 得到某一列的所有数据，不包括空数据
        /// </summary>
        /// <param name="column"></param>
        /// <param name="columnList"></param>
        public void GetColumnDataExceptEmpty(int column, List<string> columnList)
        {
            if (null == columnContainer || column < 0 || column >= columnContainer.GetLength())
            {
                Debug.LogError("获取列数据参数不合法。" + column);
                return;
            }

            columnContainer.GetLineDataExceptEmpty(column, columnList);
        }
        /// <summary>
        /// 读取路径下的Excel文件
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public bool ReadFromExcel(string filePath)
        {
            if (string.IsNullOrEmpty(filePath))
            {
                Debug.LogError("文件路径传入错误。");
                return false;
            }
            if (!filePath.Contains(".xlsx"))
            {
                Debug.LogError("此接口只能处理Excel文件。 FilePath:"+filePath);
                return false;
            }
            if(!File.Exists(filePath))
            {
                Debug.LogError("文件不存在。 FilePath:" + filePath);
                return false;
            }
            
            try
            {
                using (FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read))
                {
                    IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);

                    DataSet result = excelReader.AsDataSet();

                    int columns = result.Tables[0].Columns.Count;
                    int rows = result.Tables[0].Rows.Count;

                    if (rows > 0)
                    {
                        string firstData = result.Tables[0].Rows[0][0].ToString();
                        int beginRow = int.Parse(firstData);
                        if (7 != beginRow)
                        {
                            Debug.LogError("起始行填写错误:" + beginRow);
                            return false;
                        }

                        if (rows < 7)
                        {
                            Debug.LogError("表头数据不够:" + rows);
                            return false;
                        }

                        if (7 == rows)
                        {
                            Debug.LogError("表内除了表头没有内容。");
                            return false;
                        }

                        if (columns < 4)
                        {
                            Debug.LogError("表列数不够。" + columns);
                            return false;
                        }

                        string columnData = result.Tables[0].Rows[0][3].ToString();
                        int indexColumns = int.Parse(columnData);

                        if (indexColumns < 0 || indexColumns > columns)
                        {
                            Debug.LogError("表列数填写错误。" + indexColumns);
                            return false;
                        }

                        tableStructure = new TableStructure(SerializeUtilities.GetFileName(filePath));

                        ReadTableHeadOpStyle(result, indexColumns);

                        ReadTableData(result, beginRow, rows, columns);
                    }
                }
            }
            catch(Exception e)
            {
                if(e.GetType().Equals("System.IO.IOException"))
                {
                    Debug.LogError("文件已经打开，无法读取。 FilePath:" + filePath);
                    return false;
                }
                else
                {
                    Debug.LogError(e.Message);
                    return false;
                }
            }

            return true;
        }
        /// <summary>
        /// 海贼格式的表头读取
        /// </summary>
        private void ReadTableHeadOpStyle(DataSet result, int indexColumns)
        {
            if (null == tableStructure)
                return;

            for (int readColumn = 0; readColumn < indexColumns; ++readColumn)
            {
                string tips = result.Tables[0].Rows[1][readColumn].ToString();
                string keywordClient = result.Tables[0].Rows[2][readColumn].ToString();
                string elementType = result.Tables[0].Rows[3][readColumn].ToString();
                string indexType = result.Tables[0].Rows[4][readColumn].ToString();
                string keywordServer = result.Tables[0].Rows[5][readColumn].ToString();

                TableHead tableHead = new TableHead(tips, keywordClient, elementType, indexType, keywordServer);
                tableStructure.AddTableHead(tableHead);
            }
        }
        /// <summary>
        /// 表数据读取
        /// </summary>
        /// <param name="result"></param>
        /// <param name="beginRow"></param>
        /// <param name="rows"></param>
        /// <param name="columns"></param>
        private void ReadTableData(DataSet result, int beginRow, int rows, int columns)
        {
            beginRow--;
            rowContainer = new TableContent(rows - beginRow, columns);
            columnContainer = new TableContent(columns, rows - beginRow);

            for (int row = beginRow; row < rows; ++row)
            {
                for (int column = 0; column < columns; ++column)
                {
                    string cellData = result.Tables[0].Rows[row][column].ToString();
                    int contentRow = row - beginRow;
                    int contentColumn = column;
                    rowContainer.SetContent(contentRow, contentColumn, cellData);
                    columnContainer.SetContent(contentColumn, contentRow, cellData);
                }
            }
        }
    }
}